﻿Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class StylishComboBox
    Inherits System.Windows.Forms.ComboBox


#Region "Designer Generated Code"
    'UserControl overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private WithEvents components As System.Windows.Forms.ComboBox

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.Windows.Forms.ComboBox()
        Me.SuspendLayout()
        '
        'components
        '
        Me.components.Location = New System.Drawing.Point(0, 0)
        Me.components.Name = "StylishComboBox"
        Me.components.Size = New System.Drawing.Size(75, 23)
        Me.components.TabIndex = 0
        Me.components.DropDownStyle = ComboBoxStyle.DropDownList
        Me.components.DrawMode = Windows.Forms.DrawMode.OwnerDrawVariable
        '
        'StylishComboBox
        '
        Me.Name = "StylishComboBox"
        Me.ResumeLayout(False)
    End Sub
#End Region

    Private iImageList As ImageList = Nothing
    Public Property ImageList As ImageList
        Get
            Return Me.iImageList
        End Get
        Set(value As ImageList)
            Me.iImageList = value
        End Set
    End Property

    Private iItemBackColor As Color = SystemColors.InactiveBorder
    Private iSelectionBackColor As Color = SystemColors.Highlight
    Private iSelectionForeColor As Color = SystemColors.HighlightText

    Protected Overrides Sub OnMeasureItem(e As System.Windows.Forms.MeasureItemEventArgs)
        MyBase.OnMeasureItem(e)
    End Sub
    Protected Overrides Sub OnDrawItem(e As System.Windows.Forms.DrawItemEventArgs)

        'Lets highlight the currently selected item like any well behaved combo box should
        e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), e.Bounds)
        Dim gh As New GraphicsHelper
        If e.Index <> -1 Then
            If (TypeOf Me.Items(e.Index) Is StylishComboItem)Then
                Dim item As StylishComboItem = Me.Items(e.Index)
                If (Me.iImageList IsNot Nothing) Or (item.Image IsNot Nothing) Then
                    Dim iRect As New Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height)
                    Dim tRect As New Rectangle(e.Bounds.X + e.Bounds.Height + 2, e.Bounds.Y, e.Bounds.Width - e.Bounds.Height - 2, e.Bounds.Height)
                    Dim img As Image = Nothing
                    Try
                        If Me.iImageList IsNot Nothing Then
                            img = Me.iImageList.Images(item.ImageIndex)
                        Else
                            img = item.Image
                        End If
                    Catch ex As Exception
                        MsgBox(ex.Message)
                    End Try
                    If item.ItemDrawMode = StylishComboItemImageDrawModesEnum.DrawImageAndText Then
                        If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                            e.Graphics.FillRectangle(New SolidBrush(Me.iSelectionBackColor), e.Bounds)
                            If Not img Is Nothing Then e.Graphics.DrawImage(img, iRect)
                            gh.DrawTextNormal(e.Graphics, item.ToString, Me.Font, Me.iSelectionForeColor, tRect)
                        Else
                            e.Graphics.FillRectangle(New SolidBrush(Me.iItemBackColor), e.Bounds)
                            If Not img Is Nothing Then e.Graphics.DrawImage(img, iRect)
                            gh.DrawTextNormal(e.Graphics, item.ToString, Me.Font, Me.ForeColor, tRect)
                        End If
                    Else
                        If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                            e.Graphics.FillRectangle(New SolidBrush(Me.iSelectionBackColor), e.Bounds)
                        Else
                            e.Graphics.FillRectangle(New SolidBrush(Me.iItemBackColor), e.Bounds)
                        End If
                        Dim imgRect As Rectangle = New Rectangle(e.Bounds.X + 2, _
                                                                 e.Bounds.Y + 1, _
                                                                 e.Bounds.Width - 4, _
                                                                 e.Bounds.Height - 2)
                        e.Graphics.DrawImage(img, imgRect)
                    End If
                Else
                    If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                        e.Graphics.FillRectangle(New SolidBrush(Me.iSelectionBackColor), e.Bounds)
                        gh.DrawTextNormal(e.Graphics, item.ToString, Me.Font, Me.iSelectionForeColor, e.Bounds)
                    Else
                        e.Graphics.FillRectangle(New SolidBrush(Me.iItemBackColor), e.Bounds)
                        gh.DrawTextNormal(e.Graphics, item.ToString, Me.Font, Me.ForeColor, e.Bounds)
                    End If
                End If
            Else
                Dim item As Object = Me.Items(e.Index)
                If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
                    e.Graphics.FillRectangle(New SolidBrush(Me.iSelectionBackColor), e.Bounds)
                    gh.DrawTextNormal(e.Graphics, item.ToString, Me.Font, Me.iSelectionForeColor, e.Bounds)
                Else
                    e.Graphics.FillRectangle(New SolidBrush(Me.iItemBackColor), e.Bounds)
                    gh.DrawTextNormal(e.Graphics, item.ToString, Me.Font, Me.ForeColor, e.Bounds)
                End If
            End If
        End If

    End Sub


End Class

Public Class StylishComboItem

    Public ImageIndex As Integer = 0
    Public Image As Image = Nothing
    Public DataObject As Object = Nothing
    Public ItemDrawMode As StylishComboItemImageDrawModesEnum

    Private Sub New()
    End Sub

    Public Sub New(ImageIndex As Integer, _
                   DataObject As Object, _
                   Optional ItemDrawMode As StylishComboItemImageDrawModesEnum = StylishComboItemImageDrawModesEnum.DrawImageAndText)
        Me.ImageIndex = ImageIndex
        Me.DataObject = DataObject
        Me.ItemDrawMode = ItemDrawMode
    End Sub

    Public Sub New(Image As Image, _
                   DataObject As Object, _
                   Optional ItemDrawMode As StylishComboItemImageDrawModesEnum = StylishComboItemImageDrawModesEnum.DrawImageAndText)
        Me.Image = Image
        Me.DataObject = DataObject
        Me.ItemDrawMode = ItemDrawMode
    End Sub

    Public Overrides Function ToString() As String
        If Me.DataObject IsNot Nothing Then
            Return Me.DataObject.ToString
        Else
            Return MyBase.ToString()
        End If
    End Function

End Class

Public Enum StylishComboItemImageDrawModesEnum
    DrawImageAndText
    DrawOnlyImage
End Enum